/*
 * Componente.java	
 *
 * Copyright 2008 Universidad Francisco de Paula Santander (UFPS).
 * Todos los Derechos Reservados.
 * Creado el 07/10/08, 1o:50:38 PM
 */

package com.ufps.cuatro.modelo.representacion.componente;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JComponent;

import com.ufps.cuatro.controlador.render.UtilRender;
import com.ufps.cuatro.modelo.analizador.UtilAnalizador;
import com.ufps.cuatro.modelo.biblioteca.TipoBiblioteca;
import com.ufps.cuatro.modelo.representacion.EventoOyente;
import com.ufps.cuatro.modelo.representacion.Inicializacion;
import com.ufps.cuatro.modelo.representacion.ObjetoConstructor;
import com.ufps.cuatro.modelo.representacion.Oyente;
import com.ufps.cuatro.modelo.representacion.ParametroObjetoConstructor;
import com.ufps.cuatro.modelo.representacion.ParametroPropiedad;
import com.ufps.cuatro.modelo.representacion.PlantillaCombo;
import com.ufps.cuatro.modelo.representacion.PlantillaComponente;
import com.ufps.cuatro.modelo.representacion.Propiedad;
import com.ufps.cuatro.modelo.representacion.TipoDistribucionComponente;
import com.ufps.cuatro.modelo.representacion.TipoDistribucionPlantilla;
import com.ufps.cuatro.modelo.representacion.TipoInclusionComponente;
import com.ufps.cuatro.util.Representacion;
import com.ufps.cuatro.util.Utileria;
import com.ufps.cuatro.util.base.ComponenteBaseStandar;
import com.ufps.cuatro.util.base.ObjectBase;
import com.ufps.cuatro.util.generadores.GeneradorComponentes;
import com.ufps.cuatro.util.generadores.codeobject.CodeContextLine;
import com.ufps.cuatro.util.generadores.codeobject.EnumTypeCodeSyntax;
import com.ufps.cuatro.util.generadores.codeobject.UtilCodeContext;

/**
 * <i><b>Componente:</b></i><p>Esta Clase Abstracta es la Base para la Representación de los Controles
 * swing por Medio de Componentes Especializados.</p> 
 * <p>Un Componente es la representación abstracta de un fragmento o área de una interfaz grafica por
 * lo tanto toda la representación del modelo analizado debe estar contenida en los subtipos 
 * de esta Clase sin Excepciones.</p>
 * 
 * @author Carlos A. Torres C. - Dolly E. Guerrero. <https://code.google.com/p/tesis4dor/>
 * @version 1.0 07/10/08
 * @see ObjectBase
 */
public abstract class Componente  extends ObjectBase implements ConstComponente{
    private static final long serialVersionUID = -3065627092906206967L;    
    //asignado desde las propiedades
    private int idBiblioteca;
    //generado por la variable statica
    private int idClaseComponente;
    //utilizado para enumerar los compoentes creados en un tipo de dato
    private int idIndx = -1;
    //utilizado para ubicarWithPlantillaComponente en un componente contenedor
    private int idInGUI = -1;    
    /**
     * Indice de Ubicacion en un Contenedor (HashMap, Set, etc).
     */
    public String keyColeccion;
    /**
     * Serie Númerica para la generación de id de Objetos.
     */
    public static int serialComponente;
    private int idConstructor;            
    
    /**
     * Cadena de Definición del Control.
     */
    protected String strClassPath;
    /**
     * Alto por defecto (Este valor es el utilizado en la Matriz de Distribución, por
     * lo tanto su valor no representa información valida para asignarlo a la propiedad
     * representada del Objeto).
     */
    protected int height;
    /**
     * Ancho por defecto (Este valor es el utilizado en la Matriz de Distribución, por
     * lo tanto su valor no representa información valida para asignarlo a la propiedad
     * representada del Objeto).
     */
    protected int width;
    /**
     * Ruta de un Archivo de Configuración utilizado, en la creación del Control.
     */
    protected String strConfig;
    /**
     * Objeto que Contiene el Archivo de Configuración que se Utilizará en la
     * creación del Control.
     */
    protected File objConfig;    
    /**
     * Esta cadena representa los tokens de los Oyentes que soportará por defecto
     * el Componente.
     */
    protected String strOyentes;
    /**
     * Indica si el Componente es un Control Contenedor de Interfaz Gráfico, sin
     * embargo no es un contenedor de Alto Nivel.
     */
    protected boolean contenedor;
    /**
     * Indica el Indice del Constructor por defecto que se utilizará para instanciar objeto
     * para la creación del Control que representa el Componente.
     */
    protected int constructor;    
    /**
     * Objeto Runtime(Tiempo de ejecución) que representa el Control.
     */
    protected Class<?> objClassSwing;    
    /**
     * Indica si el Componente esta incluido en una representación.
     */
    protected boolean incluido;        
    /**
     * Letra de Identificación del Tipo de Componente, utilizada para procesos internos de depuración y 
     * generación de código y vistas previas.
     */
    protected String dni;
    
    /**
     * Indica el Modo de Inclusión en la Interfaz Gráfica.
     */
    protected TipoInclusionComponente eIncluido;
    
    private ArrayList<ObjetoConstructor> objConstructores;    
    private ArrayList<Oyente<Componente>> objOyentes;    
    private transient Object objControlSwing;
    private transient Object objContenedorSwing;            
    
    /**
     * Almacena las distribuciones del <code>Componente<code>.
     */
    protected HashMap<PlantillaCombo, PlantillaComponente> objDistribucionesIndividuales;
    
    /**
     * Contiene la Plantilla seleccionada en el Distribuidor de Componentes
     * de la Interfaz a la cual pertenece el Componente.
     * 
     */
    protected PlantillaCombo objPlantillaComboDistribucionIndividualSeleccionada;    
    private boolean finish = false;    
    /**
     * Indica el Grupo asignado en al Bibliteca de Componentes.
     */
    protected TipoBiblioteca eBiblioteca = TipoBiblioteca.eSinAsignar;
    private ArrayList<Propiedad> objPropiedadesDisponibles;            
    private ArrayList<Propiedad> objPropiedadesInternas;                                    
    
    /**
     * Esta Propiedad permite determinar si el Componente actual es heredado. 
     */
    protected boolean heredado;
    /**
     * Esta Propiedad permite establecer si el Componente actual es representado
     * como una previsualización o instancia en la Interfaz.
     */
    protected boolean previsualizar;
    /**
     * Esta Propiedad permite establecer si el Componente necesita de un modelo asociado
     * para represetnar la correcta interación en la interfaz gráfica uqe se incluirá.
     * Un Modelo Asociado es la representación de un Tipo de dato del modelo analizado,
     * esto quiere decir que un Modelo Asociado es un <code>ComponenteGenerador</code>.
     * 
     */
    protected boolean requiereModeloAsociado = false;
    /**
     * Indica si el Componente inicializa por defecto algunas de sus propiedades ó
     * de sus Componentes Generados.
     */
    protected boolean inicializacion = false;
    /**
     * Contiene las Propiedades inicializadas del Componente o de sus Componentes Generados
     * en caso de que aplique (<code>inicializacion = true</code>).
     */
    protected ArrayList<Inicializacion<Componente>> objInicializaciones;
    /**
     * Indica si el Componente distribuye sus componentes generados, de forma
     * manual, global ó automatica "por medio de plantillas de representación".
     * @deprecated Se ha optado por un nuevo y mejor diseño 
     * @see com.ufps.cuatro.modelo.representacion.Distribuidor 
     */
    protected TipoDistribucionComponente eDistribucionComponentes = TipoDistribucionComponente.eDistribucionAutomatica;
    /**
     * Indica si el Componente distribuye sus componentes generados, por medio
     * de una plantilla o manualmente.
     * @deprecated Se ha optado por un nuevo y mejor diseño 
     * @see com.ufps.cuatro.modelo.representacion.Distribuidor 
     */
    protected TipoDistribucionPlantilla eDistribucionPlantillas = TipoDistribucionPlantilla.eDistribucionManual;        
    /**
     * GridBagConstraints genérico asigando al <code>Componente</code>.
     */
    protected GridBagConstraints objGridBagConstraints;
    /**
     * Componente Base que contiene la Información necesaria para crear el Control Swing
     * que representará el <code>Componente</code>.
     */
    protected ComponenteBaseStandar objComponenteBase;   
    /**
     * Color de Representación.
     */
    public Color objColor;
    /**
     * GridBagConstraints genérico asigando al <code>Componente</code>.
     */
    protected GridBagConstraints objGridBagConstraintsGUI;
    
    /**
     * Constructor por Defecto.
     */
    public Componente() {        
        this.objConstructores = new ArrayList<ObjetoConstructor>();
        this.objOyentes = new ArrayList<Oyente<Componente>>();
        this.objPropiedadesDisponibles = new ArrayList<Propiedad>();
        this.objPropiedadesInternas = new ArrayList<Propiedad>();        
        this.objInicializaciones = new ArrayList<Inicializacion<Componente>>();
        //this.objPlantillaComboDistribucionIndividualSeleccionada = new PlantillaCombo();
        this.objDistribucionesIndividuales = new HashMap<PlantillaCombo, PlantillaComponente>();
        this.idConstructor = -1;
        this.heredado = false;
        this.previsualizar = false;
        this.dni = Utileria.leerRecursoTexto("Utileria.dni.componente");            
        this.objColor = Utileria.generateRandomColor();        
    }
    /**
     * Constructor Standard Utilizado en la App.
     * @param objComponenteBase <code>ComponenteBase</code> que contiene la Información necesaria para crear el Control Swing
     * que representará el <code>Componente</code>.
     * @param heredado Indica que el <code>Componente</code> es heredado por lo que no debe incrementar su id.
     * @param previsualizar Indica si el <code>Componente</code> es creado es previsualizado inicialmente.
     */
    public Componente(ComponenteBaseStandar objComponenteBase, boolean heredado, boolean previsualizar) {
        try{
            try {            
                this.objComponenteBase = objComponenteBase;
                this.strClassPath = objComponenteBase.getStrClassPath();
                this.objClassSwing = Class.forName(strClassPath);
                this.objConstructores = new ArrayList<ObjetoConstructor>();
                this.objOyentes = new ArrayList<Oyente<Componente>>();
                this.objPropiedadesDisponibles = new ArrayList<Propiedad>();
                this.objPropiedadesInternas = new ArrayList<Propiedad>();            
                this.objInicializaciones = new ArrayList<Inicializacion<Componente>>();            
                this.objDistribucionesIndividuales = new HashMap<PlantillaCombo, PlantillaComponente>();
                this.idConstructor = -1;            
                this.incluido = true;
                this.heredado = heredado;
                this.previsualizar = previsualizar;
                if(!heredado){
                    this.idClaseComponente = (!previsualizar) ? Componente.serialComponente++ : Componente.serialComponente;
                }
                this.dni = Utileria.leerRecursoTexto("Utileria.dni.componente");               
                this.objColor = Utileria.generateRandomColor();                
            } catch (ClassNotFoundException ex) {
                Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
            }
        }catch(java.lang.NullPointerException ex){
            UtilRender.printlnConsole("Creación de Componente Nula.", ex.getMessage(), UtilRender.ACTION_ERROR);
        }       
    }    

    /**
     * <p>Establece si el <code>Componente</code> es un Contenedor.</p>
     * <p>Un <code>Componente</code> es un Contenedor cuando puede contener
     * controles swing en su representacion ej: <code>JPanel</code></p>.
     * @param contenedor <p>Estado actual de la Propiedad que determina si el 
     * <code>Componente</code> es un Contenedor.</p>
     * <p>Un <code>Componente</code> es un Contenedor cuando puede contener
     * controles swing en su representacion ej: <code>JPanel</code></p>.
     */
    public void setContenedor(boolean contenedor) {
        this.contenedor = contenedor;
    }    

    /**
     * Establece la Referecnia del Control Swing Representado por el <code>Componente</code>.
     * @param objClassSwing Objeto <code>Class<?></code> que representa el Control Swing.
     */
    public void setObjClassSwing(Class<?> objClassSwing) {
        this.objClassSwing = objClassSwing;
    }    

    /**
     * Establece el Alto del <code>Componente</code> en unidades matriciales para 
     * su distribición en la Matriz de Representación en la Creación del <code>Componente</code>.
     * @param height Valor para la altura del <code>Componente</code>.
     */
    public void setHeight(int height) {
        this.height = height;
    }

    /**
     * Devuelve Indice del Constructor utilizado para la creacion del Control swing representado.
     * @return Indice del Constructor utilizado para la creacion del Control swing representado.
     */
    public int getIdConstructor() {
        return idConstructor;
    }

    /**
     * Establece Indice del Constructor utilizado para la creacion del Control swing representado.
     * @param idConstructor Indice del Constructor para Procesos de Instanciación (Vista Previa).
     */
    public void setIdConstructor(int idConstructor) {
        this.idConstructor = idConstructor;
    }

    /**
     * <p>Establece el Archivo de Configuración asociado al <code>Componente</code>.</p>
     * <p>Nota: El uso de este Archivo es opcional y debe estar sujeto a los
     * requerimientos de la aplicacón</p>.
     * @param objConfig Archivo de Configuración asociado al <code>Componente</code> (Si Aplica).
     */
    public void setObjConfig(File objConfig) {
        this.objConfig = objConfig;
    }

    /**
     * Establece la Cadena de Definición del Control Swing Representado.
     * @param strClassPath Cadena de Definición del Control Swing Representado.
     */
    public void setStrClassPath(String strClassPath) {
        this.strClassPath = strClassPath;
    }    

    /**
     * Establece la Cadena de Oyentes por Defecto Soportados por el Control Swing Representado.
     * @param strOyentes Cadena de Oyentes por Defecto Soportados por el Control Swing Representado.
     */
    public void setStrOyentes(String strOyentes) {
        this.strOyentes = strOyentes;
    }    

    /**
     * Establece el Ancho del <code>Componente</code> en unidades matriciales para 
     * su distribición en la Matriz de Representación en la Creación del <code>Componente</code>.
     * @param width Valor para el Ancho del <code>Componente</code>.
     */
    public void setWidth(int width) {
        this.width = width;
    }    

    /**
     * Establece el Path del Archivo de Configuración asociado al <code>Componente</code>.</p>
     * <p>Nota: El uso de este Archivo es opcional y debe estar sujeto a los
     * requerimientos de la aplicacón</p>.
     * @param strConfig Path del Archivo de Configuración asociado al <code>Componente</code>.</p>
     * <p>Nota: El uso de este Archivo es opcional y debe estar sujeto a los
     * requerimientos de la aplicacón</p>.
     */
    public void setStrConfig(String strConfig) {
        this.strConfig = strConfig;
    }       

    /**
     * Devuelve la Colección de Oyentes Soportado por el <code>Componente</code>.
     * @return Colección de Oyentes Soportado por el <code>Componente</code>.
     */
    public ArrayList<Oyente<Componente>> getObjOyentes() {
        return objOyentes;
    }

    /**
     * Establece la Colección de Oyentes Soportado por el <code>Componente</code>.
     * @param objOyentes Colección de Oyentes Soportado por el <code>Componente</code>.
     */
    public void setObjOyentes(ArrayList<Oyente<Componente>> objOyentes) {
        this.objOyentes = objOyentes;
    }       

    @Override
    public String toString() {                
        return this.objClassSwing.getSimpleName() + this.dni + this.idClaseComponente;
    }

    /**
     * Devuelve el Control Swing que Representa un Contenedor de Alto Nivel (si Aplica).
     * @return Control Swing que Representa un Contenedor de Alto Nivel (si Aplica).
     */
    public Object getObjContenedorSwing() {
        return objContenedorSwing;
    }

    /**
     * Establece el Control Swing que Representa un Contenedor de Alto Nivel (si Aplica).
     * @param objContenedorSwing Control Swing que Representa un Contenedor de Alto Nivel (si Aplica).
     */
    public void setObjContenedorSwing(Object objContenedorSwing) {
        this.objContenedorSwing = objContenedorSwing;
    }    

    /**
     * Devuelve el Control Swing que representa el <code>Componente</code>.
     * @return Control Swing que representa el <code>Componente</code>.
     */
    public Object getObjControlSwing() {
        return objControlSwing;
    }

    /**
     * Establece el Control Swing que representa el <code>Componente</code>.
     * @param objControlSwing Control Swing que representa el <code>Componente</code>.
     */
    public void setObjControlSwing(Object objControlSwing) {
        this.objControlSwing = objControlSwing;
    }    

    /**
     * Crear el Control que Representa el <code>Componente</code>.
     * @return boolean que indica el Resultado del Proceso.
     */    
    public boolean instanciar(){
        if(UtilAnalizador.estaRegistradaEnElClassPath(strClassPath)){
            if(this.getObjPlantillaComponenteDistribucionIndividualSeleccionada().getObjConstructor() != null){
                //se ha seleccionado un contructor para instanciar el objeto
                ObjetoConstructor objConstructor = this.getObjPlantillaComponenteDistribucionIndividualSeleccionada().getObjConstructor();
                //objGrafico = Utileria.crearInstancia(strClassPath, objConstructor.getOrden(), objConstructor.getObjValoresOld().toArray());
                iniciarPropiedades(objControlSwing);
            }
            else{
                objControlSwing = UtilAnalizador.crearInstancia(strClassPath);
                iniciarPropiedades(objControlSwing);
                
            }
            if(this.isContenedor()){
                String idKey = Representacion.objPropiedadesRepresentacion.getProperty("Utileria.model.generico.contenedor");
                String strClassPathContenedor =
                        Representacion.objPropiedadesRepresentacion.getProperty("Utileria.swing.control[" + idKey + "].classpath");                
                String strKey = "Utileria.swing.control[" + idKey + "].constructor";
                
                ComponenteBaseStandar objContenedorBase = GeneradorComponentes.devolverComponenteBaseClassPath(strClassPathContenedor);
                String idKeyConstructor = Representacion.objPropiedadesRepresentacion.getProperty(strKey);
                String strKeyConstructor = strKey + "[" + idKeyConstructor + "].orden";                
                String intKeyConstructor = Representacion.objPropiedadesRepresentacion.getProperty(strKeyConstructor);
                int orden = Integer.parseInt(intKeyConstructor);
                
                ObjetoConstructor objConstructor = 
                        GeneradorComponentes.crearConstructor(objContenedorBase.getObjConstructoresBase(), orden);
                
                if(objConstructor != null){
                    ParametroObjetoConstructor objParametro = objConstructor.getObjParametros().get(0);                    
                    objParametro.setObjValue(objControlSwing);                                        
                    objConstructor.setParametro(objParametro);
                    objContenedorSwing = Utileria.crearInstancia(objContenedorBase, objConstructor);                    
                }
                else{
                    objContenedorSwing = UtilAnalizador.crearInstancia(strClassPathContenedor);
                }
                return (objContenedorSwing instanceof JComponent) ? true : false;
            }
            return (objControlSwing instanceof JComponent) ? true : false;
        }
        return false;
    }
    
    /**
     * Crear el Control que Representa el <code>Componente</code>.
     * @param objControlSwing Referencia al Contrl que representa el <code>Componente</code>.
     * @return booleano que indica el Resultado del Proceso.
     */    
    public boolean instanciar(JComponent objControlSwing){
        if(UtilAnalizador.estaRegistradaEnElClassPath(strClassPath)){
            this.objControlSwing = objControlSwing;
            iniciarPropiedades(objControlSwing);            
            if(this.isContenedor()){
                String idKey = Representacion.objPropiedadesRepresentacion.getProperty("Utileria.model.generico.contenedor");
                String strClassPathContenedor =
                        Representacion.objPropiedadesRepresentacion.getProperty("Utileria.swing.control[" + idKey + "].classpath");                
                String strKey = "Utileria.swing.control[" + idKey + "].constructor";
                
                ComponenteBaseStandar objContenedorBase = GeneradorComponentes.devolverComponenteBaseClassPath(strClassPathContenedor);
                String idKeyConstructor = Representacion.objPropiedadesRepresentacion.getProperty(strKey);
                String strKeyConstructor = strKey + "[" + idKeyConstructor + "].orden";                
                String intKeyConstructor = Representacion.objPropiedadesRepresentacion.getProperty(strKeyConstructor);
                int orden = Integer.parseInt(intKeyConstructor);
                
                ObjetoConstructor objConstructor = 
                        GeneradorComponentes.crearConstructor(objContenedorBase.getObjConstructoresBase(), orden);
                
                if(objConstructor != null){
                    ParametroObjetoConstructor objParametro = objConstructor.getObjParametros().get(0);                    
                    objParametro.setObjValue(objControlSwing);                                        
                    objConstructor.setParametro(objParametro);
                    objContenedorSwing = Utileria.crearInstancia(objContenedorBase, objConstructor);                    
                }
                else{
                    objContenedorSwing = UtilAnalizador.crearInstancia(strClassPathContenedor);
                }
                return (objContenedorSwing instanceof JComponent) ? true : false;
            }
            return (objControlSwing instanceof JComponent) ? true : false;
        }
        return false;
    }
    
    private void iniciarPropiedades(Object objControl){
        try {
            Class<?> objClass = objControl.getClass();
            Method objMethod;            
            for(Propiedad objPropiedad : objPropiedadesDisponibles){                
                if(objPropiedad.isAplicada()){
                    String strNombrePropiedad = objPropiedad.getSet();
                    int sizeParam = objPropiedad.getObjParametrosSet().size();
                    Class[] objDefinicionParametros = new Class[sizeParam];
                    for(int i = 0; i < sizeParam; i++){
                        ParametroPropiedad objParametro = objPropiedad.getObjParametrosSet().get(i);
                        if(objParametro.isPrimitive()){
                            if(objParametro.getStrClassPath().equals("boolean")){
                                objDefinicionParametros[i] = Boolean.TYPE;
                            }
                            else if(objParametro.getStrClassPath().equals("byte")){
                                objDefinicionParametros[i] = Byte.TYPE;
                            }
                            else if(objParametro.getStrClassPath().equals("int")){
                                objDefinicionParametros[i] = Integer.TYPE;
                            }
                            else if(objParametro.getStrClassPath().equals("long")){
                                objDefinicionParametros[i] = Long.TYPE;
                            }        
                            else if(objParametro.getStrClassPath().equals("float")){
                                objDefinicionParametros[i] = Float.TYPE;
                            }
                            else if(objParametro.getStrClassPath().equals("double")){
                                objDefinicionParametros[i] = Double.TYPE;
                            }
                            else if(objParametro.getStrClassPath().equals("char")){
                                objDefinicionParametros[i] = Character.TYPE;
                            }                        
                        }
                        else{
                            objDefinicionParametros[i] = Class.forName(objParametro.getStrClassPath());
                        }
                    }
                    objMethod = objClass.getMethod(strNombrePropiedad, objDefinicionParametros);
                    Object[] objValorParametros = new Object[sizeParam];
                    for(int i = 0; i < sizeParam; i++){
                        ParametroPropiedad objParametro = objPropiedad.getObjParametrosSet().get(i);
                        if(objParametro.getStrClassPath().equals("java.lang.String")){
                            objValorParametros[i] = objParametro.getStrValue();
                        }
                        else if(objParametro.getStrClassPath().equals("java.lang.Boolean") ||
                                objParametro.getStrClassPath().equals("boolean")){
                            Boolean objValue = Boolean.valueOf(objParametro.getStrValue());
                            objValorParametros[i] = objValue;
                        }
                        else if(objParametro.getStrClassPath().equals("java.lang.Integer") ||
                                objParametro.getStrClassPath().equals("int")){
                            Integer objValue = Integer.valueOf(objParametro.getStrValue());
                            objValorParametros[i] = objValue;
                        }
                        else if(objParametro.getStrClassPath().equals("java.lang.Float") ||
                                objParametro.getStrClassPath().equals("float")){
                            Float objValue = Float.valueOf(objParametro.getStrValue());
                            objValorParametros[i] = objValue;
                        }
                        else if(objParametro.getStrClassPath().equals("java.lang.Double") ||
                                objParametro.getStrClassPath().equals("double")){
                            Double objValue = Double.valueOf(objParametro.getStrValue());
                            objValorParametros[i] = objValue;
                        }
                        else if(objParametro.getStrClassPath().equals("java.lang.Char") ||
                                objParametro.getStrClassPath().equals("char")){
                            Character objValue = Character.valueOf(objParametro.getStrValue().charAt(0));
                            objValorParametros[i] = objValue;
                        }
                        else if(objParametro.getStrClassPath().equals("java.lang.Byte") ||
                                objParametro.getStrClassPath().equals("byte")){
                            Byte objValue = Byte.valueOf(objParametro.getStrValue());
                            objValorParametros[i] = objValue;
                        }
                        else if(objParametro.getStrClassPath().equals("java.lang.Long") ||
                                objParametro.getStrClassPath().equals("long")){
                            Long objValue = Long.valueOf(objParametro.getStrValue());
                            objValorParametros[i] = objValue;
                        }
                    }                
                    objMethod.invoke(objControl, objValorParametros);
                    System.out.println(objClass.getSimpleName() + " : " + objMethod.getName());
                }
            }
        } catch (IllegalAccessException ex) {
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalArgumentException ex) {
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InvocationTargetException ex) {
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        } catch (NoSuchMethodException ex) {
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        } catch (SecurityException ex) {
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);          
        }        
    }   
    
    /**
     * <p>Distribuye el <code>Componente</code> en la Matriz de Objetos por medio 
     * de su <code>PlantillaComponente</code> actual seleccionada.</p>
     * <p>La distribución del <code>Componente</code> se lleva acabo por medio
     * del <code>GridBagConstraints</code> asociado a la 
     * <code>PlantillaComponente</code> actual seleccionada.</p>
     * @param objModeloTablaDistribucion Matriz de Distribución de Objetos.
     * @param modo Determina el Modo de Utilización (Obsoleto)
     * @return  Estado del Proceso de Ubicación en el Modelo de Tabla Actual.
     * @see #UBICACION_ERROR
     * @see #UBICACION_PREVIA
     * @see #UBICACION_REALIZADA
     * @see #UBICACION_SIN_PLANTILLA
     */
    public int ubicarWithGridBagConstraints(Object[][] objModeloTablaDistribucion, boolean modo){
        try{
            PlantillaComponente objTempPlantilla = this.getObjPlantillaComponenteDistribucionIndividualSeleccionada();                                
            if(objTempPlantilla == null) {
                return Componente.UBICACION_SIN_PLANTILLA;
            }
            if(!modo){                
                if(!objTempPlantilla.isIncluido()) {
                    return Componente.UBICACION_PREVIA;
                }
            }
            GridBagConstraints objTempGridBagConstraints = objTempPlantilla.getObjGridBagConstraints();
            int x = objTempGridBagConstraints.gridx;
            int y = objTempGridBagConstraints.gridy; 
            int filas = objTempGridBagConstraints.gridheight;
            int columnas = objTempGridBagConstraints.gridwidth;
            
            //Ojo Revisar
            
            for(int i = 0; i < filas; i++){//coordenadas y
                for(int j = 0; j < columnas; j++){//coordenadas x
                    objModeloTablaDistribucion[y + i][x + j] = this.getName();
                }
            }
            return Componente.UBICACION_REALIZADA;
        }catch(java.lang.ArrayIndexOutOfBoundsException ex){
            Utileria.viewConsole(this.getName());
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }catch(java.lang.NullPointerException ex){
            Utileria.viewConsole(this.getName());
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return Componente.UBICACION_ERROR;
    }
    
    /**
     * Devuelve la <code>PlantillaComponente</code> Actual Utilizada por el <code>Componente</code> para su Representación
     * en la interfaz gráfica.
     * @return <code>PlantillaComponente</code> Seleccionada.
     */
    public PlantillaComponente getObjPlantillaComponenteDistribucionIndividualSeleccionada(){
        try{
            return this.objDistribucionesIndividuales.get(this.objPlantillaComboDistribucionIndividualSeleccionada);            
        }catch(java.lang.NullPointerException ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }    

    /**
     * Devuelve la <code>PlantillaCombo</code> actual seleccionada la cual determina 
     * la distribución actual del <code>Componente</code>.
     * @return <code>PlantillaCombo</code> actual seleccionada la cual determina 
     * la distribución actual del <code>Componente</code>.
     */
    public PlantillaCombo getObjPlantillaComboDistribucionIndividualSeleccionada() {
        return objPlantillaComboDistribucionIndividualSeleccionada;
    }

    /**
     * Establece la <code>PlantillaCombo</code> actual seleccionada la cual determina 
     * la distribución actual del <code>Componente</code>.
     * @param objPlantillaComboDistribucionIndividualSeleccionada <code>PlantillaCombo</code> actual seleccionada la cual determina 
     * la distribución actual del <code>Componente</code>.
     */
    public void setObjPlantillaComboDistribucionIndividualSeleccionada(PlantillaCombo objPlantillaComboDistribucionIndividualSeleccionada) {
        this.objPlantillaComboDistribucionIndividualSeleccionada = objPlantillaComboDistribucionIndividualSeleccionada;
    }    
    
    /**
     * Devuelve la Colección de Constructores asociados al Control Representado.
     * @return Colección de Constructores asociados al Control Representado.
     */
    public ArrayList<ObjetoConstructor> getObjConstructores() {
        return objConstructores;
    }

    /**
     * Establece la Colección de Constructores asociados al Control Representado.
     * @param objConstructores
     */
    public void setObjConstructores(ArrayList<ObjetoConstructor> objConstructores) {
        this.objConstructores = objConstructores;
    }    
    
    /**
     * Indica si el <code>Componente</code> ha sido Finalizado.
     * @return boolean que Indica si el <code>Componente</code> ha sido Finalizado.
     */
    public boolean isFinish() {
        return finish;
    }

    /**
     * Establece el Estado que Indica si el <code>Componente</code> ha sido Finalizado.
     * @param finish Estado que Indica si el <code>Componente</code> ha sido Finalizado.
     */
    public void setFinish(boolean finish) {
        this.finish = finish;
    }        

    /**
     * Devuelve el Indice que identifica el <code>Componente</code> en una Colección.
     * @return Indice que identifica el <code>Componente</code> en una Colección.
     */
    public int getIdIndx() {
        return idIndx;
    }

    /**
     * Establece el Indice que identifica el <code>Componente</code> en una Colección.
     * @param idIndx Indice que identifica el <code>Componente</code> en una Colección.
     */
    public void setIdIndx(int idIndx) {
        this.idIndx = idIndx;
    }    

    @Override
    protected Object clone() {
        Componente objClon;
        //----------------------------------------------------------
        //Primero se Clona la Referencia Local
        //----------------------------------------------------------
        objClon = (Componente) super.clone();
        //----------------------------------------------------------
        //Ahora se hace la Clonación Profunda
        //----------------------------------------------------------
        //cadena de identificacion del Componente
        if(this.dni != null){
            ((Componente)objClon).dni = new String(dni.toCharArray());
        }
        //biblioteca asignada
        if(this.eBiblioteca != null){
            ((Componente)objClon).eBiblioteca = eBiblioteca;
        }        
        //llave de la colección contenida
        if(this.keyColeccion != null){
            ((Componente)objClon).keyColeccion = new String(keyColeccion.toCharArray());
        }
        //referencia al objeto swing representado
        if(this.objClassSwing != null){
            ((Componente)objClon).objClassSwing = objClassSwing;
        }
        //color de representación
        if(this.objColor != null){
            ((Componente)objClon).objColor = Utileria.generateRandomColor();
        }
        //referencia al componente base
        if(this.objComponenteBase != null){
            ((Componente)objClon).objComponenteBase = objComponenteBase;
        }
        //referencia al archivo de configuración - opcional        
        if(this.objConfig != null){
            ((Componente)objClon).objConfig = objConfig;
        }
        //constructores del Control Swing
        if(this.objConstructores != null){
            ((Componente)objClon).objConstructores = (ArrayList<ObjetoConstructor>) objConstructores.clone();
        }
        //Contenedor Swing
        if(this.objContenedorSwing != null){
            ((Componente)objClon).objContenedorSwing = objContenedorSwing;
        }
        //Control Swing
        if(this.objControlSwing != null){
            ((Componente)objClon).objControlSwing = objControlSwing;
        }
        //distribuciones        
        if(this.objDistribucionesIndividuales != null){
            ((Componente)objClon).objDistribucionesIndividuales = (HashMap<PlantillaCombo, PlantillaComponente>) objDistribucionesIndividuales.clone();
        }
        //reglas de distribución
        if(this.objGridBagConstraints != null){
            ((Componente)objClon).objGridBagConstraints = (GridBagConstraints) objGridBagConstraints.clone();
        }
        //inicializaciones de propiedades
        if(this.objInicializaciones != null){
            ((Componente)objClon).objInicializaciones = objInicializaciones;
        }
        //lista de oyentes soportados
        if(this.objOyentes != null){
            ((Componente)objClon).objOyentes = objOyentes;
        }  
        //plantilla combo seleccionada
        if(this.objPlantillaComboDistribucionIndividualSeleccionada != null){
            ((Componente)objClon).objPlantillaComboDistribucionIndividualSeleccionada = (PlantillaCombo)objPlantillaComboDistribucionIndividualSeleccionada.clone();
        }        
        //propiedades disponibles
        if(this.objPropiedadesDisponibles != null){
            ((Componente)objClon).objPropiedadesDisponibles = (ArrayList<Propiedad>) objPropiedadesDisponibles.clone();
        }
        //propiedades internas
        if(this.objPropiedadesInternas != null){
            ((Componente)objClon).objPropiedadesInternas = (ArrayList<Propiedad>) objPropiedadesInternas.clone();
        }                
        if(strClassPath != null){
            ((Componente)objClon).strClassPath = new String(strClassPath.toCharArray());
        }
        if(strConfig != null){
            ((Componente)objClon).strConfig = new String(strConfig.toCharArray());
        }
        if(strOyentes != null){
            ((Componente)objClon).strOyentes = new String(strOyentes.toCharArray());
        }                   
        return objClon;
    }    

    /**
     * Devuelve el Tipo de Biblioteca asignada al <code>Componente</code> (si aplica).
     * @return Tipo de Biblioteca asignada al <code>Componente</code> (si aplica).
     */
    public TipoBiblioteca geteBiblioteca() {
        return eBiblioteca;
    }

    /**
     * Establece el Tipo de Biblioteca asignada al <code>Componente</code> (si aplica).
     * @param eBiblioteca Tipo de Biblioteca asignada al <code>Componente</code> (si aplica).
     */
    public void seteBiblioteca(TipoBiblioteca eBiblioteca) {
        this.eBiblioteca = eBiblioteca;
    }    
    
    @Override
    public int compareTo(Object o) {        
        Componente obj = (Componente) o;
        if(this.idClaseComponente > obj.idClaseComponente) {
            return 1;
        }
        else if(this.idClaseComponente < obj.idClaseComponente) {
            return -1;
        }
        else {
            return 0;
        }
    }

    /**
     * Devuelve el Id de Ubicación en la Interfaz Grafica Asociada.
     * @return Id de Ubicación en la Interfaz Grafica Asociada.
     */
    public int getIdInGUI() {
        return idInGUI;
    }

    /**
     * Establece el Id de Ubicación en la Interfaz Grafica Asociada.
     * @param idInGUI Id de Ubicación en la Interfaz Grafica Asociada.
     */
    public void setIdInGUI(int idInGUI) {
        this.idInGUI = idInGUI;
    }

    /**
     * Devuelve la Colección de Propiedades Accesibles por el Usuario definidas en el Componente.
     * @return Colección de Propiedades Accesibles por el Usuario definidas en el Componente.
     */
    public ArrayList<Propiedad> getObjPropiedadesDisponibles() {
        return objPropiedadesDisponibles;
    }

    /**
     * Establece la Colección de Propiedades Accesibles por el Usuario definidas en el Componente.
     * @param objPropiedadesDisponibles Colección de Propiedades Accesibles por el Usuario definidas en el Componente.
     */
    public void setObjPropiedadesDisponibles(ArrayList<Propiedad> objPropiedadesDisponibles) {
        this.objPropiedadesDisponibles = objPropiedadesDisponibles;
    }
    
    /**
     * Devuelve la Colección de Propiedades Accesibles por el Sistema definidas en el Componente.
     * @return Colección de Propiedades Accesibles por el Sistema definidas en el Componente.
     */
    public ArrayList<Propiedad> getObjPropiedadesInternas() {
        return objPropiedadesInternas;
    }

    /**
     * Establece la Colección de Propiedades Accesibles por el Sistema definidas en el Componente.
     * @param objPropiedadesInternas Colección de Propiedades Accesibles por el Sistema definidas en el Componente.
     */
    public void setObjPropiedadesInternas(ArrayList<Propiedad> objPropiedadesInternas) {
        this.objPropiedadesInternas = objPropiedadesInternas;
    }
    
    /**
     * Devuelve el Estado que determina si el <code>ComponenteBase</code> tiene Propiedades
     * Disponibles asignadas.
     * @return Estado que determina si el <code>ComponenteBase</code> tiene Propiedades
     * Disponibles asignadas.
     */
    public boolean tienePropiedadesDisponibles(){
        return !this.objPropiedadesDisponibles.isEmpty();
    }
    
    /**
     * Devuelve el Estado que determina si el <code>ComponenteBase</code> tiene Propiedades
     * Internas asignadas.
     * @return Estado que determina si el <code>ComponenteBase</code> tiene Propiedades
     * Internas asignadas.
     */
    public boolean tienePropiedadesInternas(){
        return !this.objPropiedadesInternas.isEmpty();
    }

    /**
     * Devuelve el Id de Ubicación en una Biblioteca.
     * @return Id de Ubicación en una Biblioteca.
     */
    public int getIdBiblioteca() {
        return idBiblioteca;
    }

    /**
     * Establece el Id de Ubicación en una Biblioteca.
     * @param idBiblioteca Id de Ubicación en una Biblioteca.
     */
    public void setIdBiblioteca(int idBiblioteca) {
        this.idBiblioteca = idBiblioteca;
    }

    /**
     * Devuelve el Id de Generación del Componente.
     * @return Id de Generación del Componente.
     */
    public int getIdClaseComponente() {
        return idClaseComponente;
    }

    /**
     * Establece el Id de Generación del Componente.
     * @param idClaseComponente Id de Generación del Componente.
     */
    public void setIdClaseComponente(int idClaseComponente) {
        this.idClaseComponente = idClaseComponente;
    }    

    /**
     * Permite evaluar si el Componente representa un Control swing Contenedor.
     * @return boolean que indica si el Componente representa un Control swing Contenedor.
     */
    public boolean isContenedor() {
        return contenedor;
    }

    /**
     * Devuelve el Id dentro de la Colección donde está incluido (si aplica).
     * @return Id dentro de la Colección donde está incluido (si aplica).
     */
    public int getIdColeccion() {
        return idColeccion;
    }    

    /**
     * Devuelve la Altura del Componente en unidades matriciales (formato de la Aplicación).     
     * @return Altura del Componente en unidades matriciales (formato de la Aplicación).     
     */
    public int getHeight() {
        return height;
    }

    /**
     * Devuelve el key de Ubicacion en un Contenedor (HashMap, Set, etc).
     * @return Key de Ubicacion en un Contenedor (HashMap, Set, etc).
     */
    public String getKeyColeccion() {
        return keyColeccion;
    }

    /**
     * Devuelve el Objeto <code>Class<?></code> del Control representado por el Componente. 
     * @return <code>Class<?></code> del Control representado por el Componente. 
     */
    public Class<?> getObjClassSwing() {
        return objClassSwing;
    }

    /**
     * Devuelve el Archivo de Configuración para el Componente (si aplica). este archivo define
     * propiedades extras  que serán utilizadas en los procesos de Generación de Componentes,
     * Vistas Previas y/ó Generación de Código.
     * @return Archivo de Configuración para el Componente (si aplica).
     */
    public File getObjConfig() {
        return objConfig;
    }    

    /**
     * Devuelve el ClassPath del Control representado por el Componente. 
     * @return ClassPath del Control representado por el Componente. 
     */
    public String getStrClassPath() {
        return strClassPath;
    }

    /**
     * Devuelve el Path ó Ruta del Archivo de Configuración para el Componente (si aplica). este archivo define
     * propiedades extras  que serán utilizadas en los procesos de Generación de Componentes,
     * Vistas Previas y/ó Generación de Código.
     * @return Path ó Ruta del Archivo de Configuración para el Componente (si aplica).
     */
    public String getStrConfig() {
        return strConfig;
    }

    

    /**
     * Devuelve la Cadena de Oyentes asociados al Control Swing representado por el Componente.
     * @return Cadena de Oyentes asociados al Control Swing representado por el Componente.
     */
    public String getStrOyentes() {
        return strOyentes;
    }    

    /**
     * Devuelve la Anchura del Componente en unidades matriciales (formato de la Aplicación).     * 
     * @return Anchura del Componente en unidades matriciales (formato de la Aplicación).     * 
     */
    public int getWidth() {
        return width;
    }

    /**
     * Establece el Id dentro de la Colección donde está incluido (si aplica).
     * @param IdColeccion Id dentro de la Colección donde está incluido (si aplica).
     */
    public void setIdColeccion(int IdColeccion) {
        this.idColeccion = IdColeccion;
    }
    
    /**
     * Establece el key de Ubicacion en un Contenedor (HashMap, Set, etc).
     * @param keyColeccion key de Ubicacion en un Contenedor (HashMap, Set, etc).
     */
    public void setKeyColeccion(String keyColeccion) {
        this.keyColeccion = keyColeccion;
    }        

    /**
     * Devuelve el Id del Constructor utilizado por el Control Swing  representado por el 
     * Componente.
     * @return Id del Constructor utilizado por el Control Swing  representado por el 
     * Componente.
     */
    public int getConstructor() {
        return constructor;
    }

    /**
     * Establece el Id del Constructor utilizado por el Control Swing  representado por el 
     * Componente.
     * @param constructor Id del Constructor utilizado por el Control Swing  representado por el 
     * Componente.
     */
    public void setConstructor(int constructor) {
        this.constructor = constructor;
    }
    
    /**
     * Devuelve el Valor de la Propiedad requerida en el Parametro.
     * @param strName Nombre de la Propiedad Solicitada.
     * @return Propiedad requerida en el Parametro (si existeArchivo ó null).
     */
    public Object getValuePropiedad(String strName){
        if(this.objPropiedadesDisponibles == null) {
            return "No Definida";
        }
        for(Propiedad objTempPropiedad : this.objPropiedadesDisponibles){
            String strNamePropiedad = objTempPropiedad.getName().toLowerCase();
            if(strNamePropiedad.toLowerCase().equals(strName.toLowerCase())){
                ParametroPropiedad objParametro = objTempPropiedad.getObjParametrosSet().get(0);
                return objParametro.getStrValue();
            }
        }
        return "No Definida";
    }

    /**
     * Indica si el Componente ha sido heredado, esto indica que no deberia crear
     * ni inicializar propiedades propias ya que su instancia es utilizada por un
     * subtipo. Este caso se presenta cuando se crean subtipos de las clases base.
     * @return boolean que Indica si el Componente ha sido heredado.
     */
    public boolean isHeredado() {
        return heredado;
    }    

    /**
     * Indica si el Componente es Previsualizado, esto indica que el Componente
     * inicializa propiedades de instanciación en la interfaz pero no genera si
     * id de generación ya que por el momento solo es utilizado como candidato
     * a ser creado. Este caso se presenta cuando se representan <code>ComponentesContenedores</code>
     * y <code>ComponentesGeneradoresContenedores</code>.
     * @return boolean que Indica si el Componente es Previsualizado.
     */
    public boolean isPrevisualizar() {
        return previsualizar;
    }       
    
    /**
     * Indica si el Componente Generado ha sido Incluido en la Represnetación de
     * su Componente Parent (<code>Componente Extra</code>, <code>Componente Contenedor</code>) ó
     * <code>Componente Generador</code>. Los Componentes Generados pueden ser incluidos o no,
     * deacuerdo a las necesidades del usuario por lo tanto esta propiedad indica ese estado.
     * @return boolean que Indica si el Componente Generador ha sido Incluido en la Represnetación de
     * su Componente Parent.
     */
    public boolean isIncluido() {
        return incluido;
    }

    /**
     * Establece si el Componente Generado ha sido Incluido en la Represnetación de
     * su Componente Parent (<code>Componente Extra</code>, <code>Componente Contenedor</code>) ó
     * <code>Componente Generador</code>. Los Componentes Generados pueden ser incluidos o no,
     * deacuerdo a las necesidades del usuario por lo tanto esta propiedad indica ese estado.
     * @param incluido boolean que Indica si el Componente Generador ha sido Incluido en la Represnetación de
     * su Componente Parent.
     */
    public void setIncluido(boolean incluido) {
        this.incluido = incluido;
    }

    /**
     * Devuelve el Modo de Inclusión del Componente (Metodo - Clase - Contenedor).
     * @return Modo de Inclusión del Componente.
     */
    public TipoInclusionComponente geteIncluido() {
        return eIncluido;
    }

    /**
     * Establece el Modo de Inclusión del Componente (Metodo - Clase - Contenedor).
     * @param eIncluido Modo de Inclusión del Componente.
     */
    public void seteIncluido(TipoInclusionComponente eIncluido) {
        this.eIncluido = eIncluido;
    }

    /**
     * Devuelve el estado que indica si el Componente Inicializa propiedades.
     * @return indica estado que indica si el Componente Inicializa propiedades.
     */
    public boolean isInicializacion() {
        return inicializacion;
    }

    /**
     * Establece el estado que indica si el Componente Inicializa propiedades.
     * @param inicializacion estado que indica si el Componente Inicializa propiedades.
     */
    public void setInicializacion(boolean inicializacion) {
        this.inicializacion = inicializacion;
    }

    /**
     * Devuelve el estado que indica si el Componente tiene un modelo asociado para su
     * visualización en la interfaz grafica asociado.
     * @return estado que indica si el Componente tiene un modelo asociado para su
     * visualización en la interfaz grafica asociado.
     */
    public boolean isModeloAsociado() {
        return requiereModeloAsociado;
    }    

    /**
     * Devuelve la Colección de Inicializaciones para este Componente y sus Componentes
     * Generados.
     * @return Colección de Inicializaciones para este Componente y sus Componentes
     * Generados.
     */
    public ArrayList<Inicializacion<Componente>> getObjInicializaciones() {
        return objInicializaciones;
    }

    /**
     * Estabelce la Colección de Inicializaciones para este Componente y sus Componentes
     * Generados.
     * @param objInicializaciones Colección de Inicializaciones para este Componente y sus Componentes
     * Generados.
     */
    public void setObjInicializaciones(ArrayList<Inicializacion<Componente>> objInicializaciones) {
        this.objInicializaciones = objInicializaciones;
    }    
    
    /**
     * Indica que el Componente será creado. Este método finaliza la creación del 
     * Componente y asigna su id de Representación y otras propiedades que le
     * permitirá ser representado en la Generación de Código.
     */
    public abstract void ok();    
    
    /**
     * Permite buscar <code>Componente</code> agregados a la tabla de distribución.
     * @param objComponente <code>Componente</code>
     * @param strName Nombre del <code>Componente</code>
     * @return boolean que permite establecer si el componente esta agregado a la tabla de distribución.
     */
    protected boolean isEncontrado(Componente objComponente, String strName){
        for(Propiedad objPropiedad : objComponente.getObjPropiedadesDisponibles()){
            if(objPropiedad.getObjParametrosSet().get(0).getStrValue().equals(strName)){
               return true;
            }
        }
        return false;
    }
    
    /**
     * Determina si existeArchivo una <code>PlantillaComponente</code> asociada al <code>Componente</code>
     * con la distribución actual seleccionada.
     * @return boolean que determina si existeArchivo una <code>PlantillaComponente</code> asociada al <code>Componente</code>
     * con la distribución actual seleccionada.
     */
    public boolean isPlantillaComponenteGenerada(){
        if(this.eDistribucionComponentes == TipoDistribucionComponente.eDistribucionGlobal){
            return this.isPlantillaComponenteGenerada(TipoDistribucionComponente.eDistribucionGlobal);
        }
        else if(this.eDistribucionComponentes == TipoDistribucionComponente.eDistribucionManual){
            return this.isPlantillaComponenteGenerada(TipoDistribucionComponente.eDistribucionManual);
        }
        return this.isPlantillaComponenteGenerada(TipoDistribucionComponente.eDistribucionAutomatica);
    }
    
    /**
     * Determina si existeArchivo una <code>PlantillaComponente</code> asociada al <code>Componente</code>
     * con la distribución pasada en el parametro.
     * @param eDistribucionTemp <code>TipoDistribución</code> que se evaluará.
     * @return boolean que determina si existeArchivo una <code>PlantillaComponente</code> asociada al <code>Componente</code>
     * con la distribución actual seleccionada.
     */
    public boolean isPlantillaComponenteGenerada(TipoDistribucionComponente eDistribucionTemp){
        if(eDistribucionTemp == TipoDistribucionComponente.eDistribucionGlobal){
            //return (this.objPlantillaComponenteGlobal == null) ? false : true;
        }
        else if(eDistribucionTemp == TipoDistribucionComponente.eDistribucionManual){
            //return (this.objPlantillaComponenteManual == null) ? false : true;
        }
        //return (this.objPlantillaComponenteAutomatica == null) ? false : true;
        return true;
    }
    
    /**
     * Genera y asigna una Plantilla para el <code>Componente</code>.
     * @param y Valor en el eje x.
     * @param x Valor en el eje y.
     * @param manual Tipo de Plantilla que se encapsulará.
     * @return estado del Proceso.
     */
    public boolean encapsularPlantillaComponente(int y, int x, boolean manual){
        try{
            PlantillaComponente objPlantillaComponente = 
                    GeneradorComponentes.crearPlantillaComponenteDefault(this);
            
            objPlantillaComponente.setX(x);
            objPlantillaComponente.setY(y);                                                
            objPlantillaComponente.setIncluido(true);   

//            if(manual){                
//                this.objPlantillaComponenteManual = objPlantillaComponente;
//            }
//            else{
//                this.objPlantillaComponenteGlobal = objPlantillaComponente;
//            }
            return true;
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return false;
    }
    
    /**
     * Genera y asigna una Plantilla para el <code>Componente</code>.
     * @param y Valor en el eje x.
     * @param x Valor en el eje y.
     * @param manual Tipo de Plantilla que se encapsulará.
     * @return estado del Proceso.
     */
    public boolean encapsularPlantillaComponente2(int y, int x, boolean manual){
        try{
            PlantillaComponente objPlantillaComponente = 
                    GeneradorComponentes.crearPlantillaComponenteDefault(this);
            
            objPlantillaComponente.setX(x);
            objPlantillaComponente.setY(y);                                                
            objPlantillaComponente.setIncluido(true);   

            if(manual){                
                //this.objPlantillaComponenteManual = objPlantillaComponente;
            }
            else{
                //this.objPlantillaComponenteGlobal = objPlantillaComponente;
            }
            return true;
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }        
        return false;
    }

    /**
     * Devuelve el Tipo de Distribución para el <code>Componente</code>.
     * @return Tipo de Distribución para el <code>Componente</code>.
     */
    public TipoDistribucionComponente geteDistribucionComponentes() {
        return eDistribucionComponentes;
    }

    /**
     * Devuelve Tipo de Distribución de la Plantilla para el <code>Componente</code>.
     * @return Tipo de Distribución de la Plantilla para el <code>Componente</code>.
     */
    public TipoDistribucionPlantilla geteDistribucionPlantillas() {
        return eDistribucionPlantillas;
    }   
    
    /**
     * Devuelve el GridBagConstraints genérico asigando al <code>Componente</code>.
     * @return GridBagConstraints genérico asigando al <code>Componente</code>.
     */
    public GridBagConstraints getObjGridBagConstraints() {
        return objGridBagConstraints;
    }

    /**
     * Establece el GridBagConstraints genérico asigando al <code>Componente</code>.
     * @param objGridBagConstraints GridBagConstraints genérico asigando al <code>Componente</code>.
     */
    public void setObjGridBagConstraints(GridBagConstraints objGridBagConstraints) {
        this.objGridBagConstraints = objGridBagConstraints;
    }

    /**
     * Devuelve el Componente Base que contiene la Información necesaria para crear el Control Swing
     * que representará el <code>Componente</code>.
     * @return Componente Base que contiene la Información necesaria para crear el Control Swing
     * que representará el <code>Componente</code>.
     */
    public ComponenteBaseStandar getObjComponenteBase() {
        return objComponenteBase;
    }
    
    /**
     * <p>Devuelve el Nombre Asociado al <code>Componente</code>.</p>
     * <p>Este Método es un envoltorio de la <code>Propiedad</code> "Name" por lo tanto
     * se asume que el <code>Componente</code> debe tener asiganda esa <code>Propiedad</code>.
     * En caso de no presentarla el <code>Componente</code> devuelve su <code>toString</code>.</p>
     * @return Nombre Asociado al <code>Componente</code>.
     * @see #toString() 
     * @see com.ufps.cuatro.modelo.representacion.Propiedad
     */
    public String getName(){
        String strNombre = GeneradorComponentes.getValorPropiedad(this, "Name");
        if(strNombre.isEmpty()){
            strNombre = this.toString();
        }
        return strNombre;
    }
    
    /**
     * <p>Establece el Nombre Asociado al <code>Componente</code>.</p>
     * <p>Este Método es un envoltorio de la <code>Propiedad</code> "Name" por lo tanto
     * se asume que el <code>Componente</code> debe tener asiganda esa <code>Propiedad</code>.
     * En caso de no presentarla el <code>Componente</code> devuelve su <code>toString</code>.</p>          
     * @param strName Nuevo nombre que se aplicará al <code>Componente</code>
     * @see com.ufps.cuatro.modelo.representacion.Propiedad
     */
    public void setName(String strName){
        GeneradorComponentes.setValorPropiedadString(this, "Name", strName);        
    }
    
    /**
     * Devuelve el <code>GridBagConstraints</code> de la Plantilla Activa asignada al <code>Componente</code>.
     * <p>Nota: En caso de no presentar una <code>PlantillaComponente</code> Válida ó <code>GridBagConstraints</code> asociado
     * a la <code>PlantillaComponente</code> actual, se devolverá el <code>GridBagConstraints</code> genérico del 
     * <code>Componente</code>.</p>
     * @return GridBagConstraints <code>GridBagConstraints</code> de la Plantilla Activa asignada al <code>Componente</code>.
     * <p>Nota: En caso de no presentar una <code>PlantillaComponente</code> Válida ó <code>GridBagConstraints</code> asociado
     * a la <code>PlantillaComponente</code> actual, se devolverá el <code>GridBagConstraints</code> genérico del 
     * <code>Componente</code>.</p>
     */
    public GridBagConstraints getGridBagConstraintsActiva(){
        try{            
            PlantillaComponente objPlantillaSeleccionada = this.getObjPlantillaComponenteDistribucionIndividualSeleccionada();
            GridBagConstraints objTempConstraints = objPlantillaSeleccionada.getObjGridBagConstraints();
            //Actualizacion de los Tamañaos del Componente Distribuidor
            if(this instanceof ComponenteDistribuidor){
                ComponenteDistribuidor objComponenteDistribuidor = (ComponenteDistribuidor) this;
                if(objComponenteDistribuidor.existeDistribucionGrupalSeleccionada()){
                    int gridwidth = 0;
                    int gridheight = 0;
                    ArrayList<Componente> objComponentes = objComponenteDistribuidor.getObjDistribuidorGrupalSeleccionado().objComponentesDistribuidos;
                    for(Componente objComponente : objComponentes){
                        GridBagConstraints objConstraints = objComponente.getGridBagConstraintsActiva();
                        //GridBagConstraints objConstraints = objComponente.getGridBagConstraintsActivaNormalizada();
                        gridwidth += objConstraints.gridwidth;
                        gridheight += objConstraints.gridheight;
                    }
                    //Se Actualiza al Nuevo Tamaño
                    if((gridwidth != objTempConstraints.gridwidth) && (gridheight != objTempConstraints.gridheight)){
                        objTempConstraints.gridwidth = gridwidth;
                        objTempConstraints.gridheight = gridheight;
                    }
                }                
            }
            //else if(this instanceof ComponenteGenerado){
            //    objTempConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
            //}
            return objTempConstraints;
        }catch(java.lang.NullPointerException ex){ 
            //Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
            Utileria.viewConsole("GridBagConstraints Activa: Plantilla Componente, PlantillaCombo ó GridBagContraint Nulos en Componente:" + this.getName());
        }
        return this.objGridBagConstraints;
    }
    
    /**
     * 
     * @return
     */
    public GridBagConstraints getGridBagConstraintsActivaNormalizada(){
        try{            
            PlantillaComponente objPlantillaSeleccionada = this.getObjPlantillaComponenteDistribucionIndividualSeleccionada();
            GridBagConstraints objTempConstraints = objPlantillaSeleccionada.getObjGridBagConstraints();
            //Actualizacion de los Tamañaos del Componente Distribuidor
            if(this instanceof ComponenteDistribuidor){
                ComponenteDistribuidor objComponenteDistribuidor = (ComponenteDistribuidor) this;                
                Object[][] objDistribucion = objComponenteDistribuidor.getObjDistribuidorGrupalSeleccionado().objDataTablaDistribucion;
                int size = objDistribucion.length;                
                int[] arraySize = new int[size];
                for(int i = 0; i < size; i++){                    
                    int usados = 0;
                    for(int j = 0; j < objComponenteDistribuidor.getObjDistribuidorGrupalSeleccionado().getSizeWidthColection(); j++){
                        try{
                            if(objDistribucion[i][j] instanceof String){
                                String strTemp = (String) objDistribucion[i][j];
                                if(!strTemp.isEmpty()){
                                    usados++;
                                }
                            }
                        }catch(java.lang.ArrayIndexOutOfBoundsException ex){
                            break;
                        }
                    }
                    arraySize[i] = usados;
                }
                int gridWidth = 0;
                int gridHeight = 0;
                for(int i = 0; i < arraySize.length; i++){
                    if(gridWidth < arraySize[i])gridWidth = arraySize[i];
                    if(arraySize[i] > 0)gridHeight++;
                }
                //Se Actualiza al Nuevo Tamaño
                if((gridWidth != objTempConstraints.gridwidth) && (gridHeight != objTempConstraints.gridheight)){
                    objTempConstraints.gridwidth = gridWidth;
                    objTempConstraints.gridheight = gridHeight;
                }
            }
            return objTempConstraints;
        }catch(java.lang.NullPointerException ex){ 
            //Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
            Utileria.viewConsole("GridBagConstraints Activa Normalizada: Plantilla Componente, PlantillaCombo ó GridBagContraint Nulos en Componente:" + this.getName());
        }
        return this.objGridBagConstraints;
    }
    
    /**
     * Devuelve por medio del <code>PlantillaCombo</code> el <code>GridBagConstraints</code> de la <code>PlantillaComponente</code> asignada al <code>Componente</code>.
     * <p>Nota: En caso de no presentar una <code>PlantillaComponente</code> Válida ó <code>GridBagConstraints</code> asociado
     * a la <code>PlantillaComponente</code> actual, se devolverá el <code>GridBagConstraints</code> genérico del 
     * <code>Componente</code>.</p>
     * @param objPlantillaCombo 
     * @return GridBagConstraints <code>GridBagConstraints</code> de la Plantilla Activa asignada al <code>Componente</code>.
     * <p>Nota: En caso de no presentar una <code>PlantillaComponente</code> Válida ó <code>GridBagConstraints</code> asociado
     * a la <code>PlantillaComponente</code> actual, se devolverá el <code>GridBagConstraints</code> genérico del 
     * <code>Componente</code>.</p>
     */
    public GridBagConstraints getGridBagConstraintsPorPlantillaCombo(PlantillaCombo objPlantillaCombo){
        try{            
            PlantillaComponente objPlantillaSeleccionada = this.getObjPlantillaComponenteDistribucionIndividual(objPlantillaCombo);
            GridBagConstraints objTempConstraints = objPlantillaSeleccionada.getObjGridBagConstraints();
            //Actualizacion de los Tamañaos del Componente Distribuidor
            if(this instanceof ComponenteDistribuidor){
                ComponenteDistribuidor objComponenteDistribuidor = (ComponenteDistribuidor) this;
                if(objComponenteDistribuidor.existeDistribucionGrupalSeleccionada()){
                    int gridwidth = 0;
                    int gridheight = 0;
                    ArrayList<Componente> objComponentes = objComponenteDistribuidor.getObjDistribuidorGrupalSeleccionado().objComponentesDistribuidos;
                    for(Componente objComponente : objComponentes){
                        GridBagConstraints objConstraints = objComponente.getGridBagConstraintsPorPlantillaCombo(objPlantillaCombo);
                        gridwidth += objConstraints.gridwidth;
                        gridheight += objConstraints.gridheight;
                    }
                    //Se Actualiza al Nuevo Tamaño
                    if(gridwidth != objTempConstraints.gridwidth && gridheight != objTempConstraints.gridheight){
                        objTempConstraints.gridwidth = gridwidth;
                        objTempConstraints.gridheight = gridheight;
                    }
                }                
            }
            return objTempConstraints;
        }catch(java.lang.NullPointerException ex){ 
            //Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("getGridBagConstraintsActiva: Plantilla Componente, PlantillaCombo ó GridBagContraint Nulos en Componente:" + this.getName());
        }
        return this.objGridBagConstraints;
    }
    
    /**
     * 
     * @param objComponenteDistribuidor
     * @param objPlantillaCombo
     * @return
     */
    protected int limiteHorizontalDistribuido(ComponenteDistribuidor objComponenteDistribuidor, PlantillaCombo objPlantillaCombo){
        int gridwidth = 0;        
        ArrayList<Componente> objComponentes = objComponenteDistribuidor.getObjDistribuidorGrupalSeleccionado().objComponentesDistribuidos;
        for(Componente objComponente : objComponentes){
            GridBagConstraints objConstraints = objComponente.getGridBagConstraintsPorPlantillaCombo(objPlantillaCombo);
            if(gridwidth < (objConstraints.gridx + objConstraints.gridwidth)){
                gridwidth = objConstraints.gridx + objConstraints.gridwidth;
            }            
        }
        return gridwidth;
    }
    
    /**
     * 
     * @param objComponenteDistribuidor
     * @param objPlantillaCombo
     * @return
     */
    protected int limiteVerticalDistribuido(ComponenteDistribuidor objComponenteDistribuidor, PlantillaCombo objPlantillaCombo){
        int gridheight = 0;        
        ArrayList<Componente> objComponentes = objComponenteDistribuidor.getObjDistribuidorGrupalSeleccionado().objComponentesDistribuidos;
        for(Componente objComponente : objComponentes){
            GridBagConstraints objConstraints = objComponente.getGridBagConstraintsPorPlantillaCombo(objPlantillaCombo);
            if(gridheight < (objConstraints.gridy + objConstraints.gridheight)){
                gridheight = objConstraints.gridy + objConstraints.gridheight;
            }            
        }
        return gridheight;
    }
    
    /**
     * Actualiza <code>GridBagConstraints</code> de la Plantilla Activa asignada al <code>Componente</code>.
     */
    protected abstract void actualizarGridBagConstraintsActiva();
    
    /**
     * Establece el <code>GridBagConstraints</code> de la Plantilla Activa asignada al <code>Componente</code>.
     * <p>Nota: En caso de no presentar una <code>PlantillaComponente</code> Válida ó <code>GridBagConstraints</code> asociado
     * a la <code>PlantillaComponente</code> actual, se actualizará el <code>GridBagConstraints</code> genérico del 
     * <code>Componente</code>.</p>
     * @param objNewGridBagConstraints <code>GridBagConstraints</code> de la Plantilla Activa asignada al <code>Componente</code>.
     * <p>Nota: En caso de no presentar una <code>PlantillaComponente</code> Válida ó <code>GridBagConstraints</code> asociado
     * a la <code>PlantillaComponente</code> actual, se actualizará el <code>GridBagConstraints</code> genérico del 
     * <code>Componente</code>.</p>
     */
    public void setGridBagConstraintsActiva(GridBagConstraints objNewGridBagConstraints){
        try{
            this.getObjPlantillaComponenteDistribucionIndividualSeleccionada().setObjGridBagConstraints(objNewGridBagConstraints);
            return;
        }catch(java.lang.NullPointerException ex){  
            //Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
            System.out.println("setGridBagConstraintsActiva: Plantilla Componente, PlantillaCombo ó GridBagContraint Nulos en Componente:" + this.getName());
        }
        this.setObjGridBagConstraints(objNewGridBagConstraints);
    }

    /**
     * 
     * @return
     */
    public HashMap<PlantillaCombo, PlantillaComponente> getObjDistribucionesIndividuales() {
        return objDistribucionesIndividuales;
    }
    
    /**
     * 
     * @param objPlantillaComboDistribucionIndividualSeleccionada 
     * @return
     */
    public PlantillaComponente getObjPlantillaComponenteDistribucionIndividual(PlantillaCombo objPlantillaComboDistribucionIndividualSeleccionada) {
        this.objPlantillaComboDistribucionIndividualSeleccionada = objPlantillaComboDistribucionIndividualSeleccionada;
        return objDistribucionesIndividuales.get(objPlantillaComboDistribucionIndividualSeleccionada);
    }

    /**
     * 
     * @param objDistribuciones 
     */
    public void setObjDistribucionesIndividuales(HashMap<PlantillaCombo, PlantillaComponente> objDistribuciones) {
        this.objDistribucionesIndividuales = objDistribuciones;
    }
    
    /**
     * 
     * @param objPlantillaCombo
     * @param objPlantillaComponente
     * @return
     */
    public boolean agregarDistribucionIndividual(PlantillaCombo objPlantillaCombo, PlantillaComponente objPlantillaComponente){
        this.objDistribucionesIndividuales.put(objPlantillaCombo, objPlantillaComponente);
        return false;
    }
    
    /**
     * 
     * @param objPlantillaCombo
     * @param objPlantillaComponente
     * @return
     */
    public boolean actualizarDistribucionIndividual(PlantillaCombo objPlantillaCombo, PlantillaComponente objPlantillaComponente){
        this.objDistribucionesIndividuales.put(objPlantillaCombo, objPlantillaComponente);
        return false;
    }
    
    /**
     * 
     * @return
     */
    public boolean existenDistribucionesIndividuales(){
        return !this.objDistribucionesIndividuales.isEmpty();        
    }
    
    /**
     * 
     * @param objPlantillaCombo
     * @return
     */
    public PlantillaComponente devolverDistribuciónIndividual(PlantillaCombo objPlantillaCombo){
        return this.objDistribucionesIndividuales.get(objPlantillaCombo);
    }
    
    /**
     * 
     * @param objPlantillaCombo
     * @return
     */
    public PlantillaComponente eliminarDistribucionIndividual(PlantillaCombo objPlantillaCombo){
        return this.objDistribucionesIndividuales.remove(objPlantillaCombo);        
    }
    
    /**
     * 
     * @param objPlantillaCombo
     * @return
     */
    public boolean existeDistribucionIndividual(PlantillaCombo objPlantillaCombo){
        return this.objDistribucionesIndividuales.containsKey(objPlantillaCombo);
    }
    
    /**
     * 
     * @param objPlantillaComponente
     * @return
     */
    public boolean existePlantillaComponente(PlantillaComponente objPlantillaComponente){
        return this.objDistribucionesIndividuales.containsValue(objPlantillaComponente);
    }

    /**
     * 
     * @return
     */
    public GridBagConstraints getObjGridBagConstraintsGUI() {
        if(objGridBagConstraintsGUI != null){
            try{
                GridBagConstraints objTempConstraints = objGridBagConstraintsGUI;
                //Actualizacion de los Tamañaos del Componente Distribuidor
                if(this instanceof ComponenteDistribuidor){
                    ComponenteDistribuidor objComponenteDistribuidor = (ComponenteDistribuidor) this;
                    if(objComponenteDistribuidor.existeDistribucionGrupalSeleccionada()){
                        int gridwidth = 0;
                        int gridheight = 0;
                        ArrayList<Componente> objComponentes = objComponenteDistribuidor.getObjDistribuidorGrupalSeleccionado().objComponentesDistribuidos;
                        for(Componente objComponente : objComponentes){
                            GridBagConstraints objConstraints = objComponente.getGridBagConstraintsActiva();
                            gridwidth += objConstraints.gridwidth;
                            gridheight += objConstraints.gridheight;
                        }
                        //Se Actualiza al Nuevo Tamaño
                        if((gridwidth != objTempConstraints.gridwidth) && (gridheight != objTempConstraints.gridheight)){
                            objTempConstraints.gridwidth = gridwidth;
                            objTempConstraints.gridheight = gridheight;
                        }
                    }                
                }
                return objTempConstraints;
            }catch(java.lang.NullPointerException ex){ 
                //Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
                Utileria.viewConsole("getGridBagConstraintsActiva: Plantilla Componente, PlantillaCombo ó GridBagContraint Nulos en Componente:" + this.getName());
            }
        }
        else{
            objGridBagConstraintsGUI = getGridBagConstraintsActiva();
        }
        return objGridBagConstraintsGUI;
    }

    /**
     * 
     * @param objGridBagConstraintsGUI
     */
    public void setObjGridBagConstraintsGUI(GridBagConstraints objGridBagConstraintsGUI) {
        this.objGridBagConstraintsGUI = objGridBagConstraintsGUI;
    }

    /**
     * 
     * @return
     */
    public String getDni() {
        return dni;
    }

    /**
     * 
     * @return
     */
    public boolean isRequiereModeloAsociado() {
        return requiereModeloAsociado;
    }
    
    /**
     * Determina si el Control Representado por el <code>Componente</code> es un
     * Contenedor de Colecciones de Objetos.
     * @return boolean que determina el si el Control Representado por el 
     * <code>Componente</code> es un Contenedor de Colecciones de Objetos.
     */
    public boolean isComponentCollection(){
        try {
            if(objClassSwing.newInstance() instanceof javax.swing.JList ||
                    objClassSwing.newInstance() instanceof javax.swing.JComboBox ||
                    objClassSwing.newInstance() instanceof javax.swing.JTable ||
                    objClassSwing.newInstance() instanceof javax.swing.JTree){
                return true;
            }
        } catch (InstantiationException ex) {
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }
    
    /**
     * Determina si el Control Representado por el <code>Componente</code> debe
     * definir Eventos.
     * @return boolean que determina si el Control Representado por el <code>Componente</code> debe
     * definir Eventos.
     */
    public boolean isDefinedEvents(){
        try{
            return !objOyentes.isEmpty();
        }catch(java.lang.NullPointerException ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return false;
    }    
    
    /**
     * Genera y devuelve una colección de Código fuente del Tipo de Sintaxis solicitada para la representación del <code>Componente</code>.
     * @param strEnumTypeCodeSyntax Nombre de la Enumeración.
     * @return Colección de Lineas de Código Fuente.
     */
    public ArrayList<CodeContextLine> generateSourceCodeSyntax(String strEnumTypeCodeSyntax){
        EnumTypeCodeSyntax eTypeCodeSyntax = EnumTypeCodeSyntax.valueOf(strEnumTypeCodeSyntax);
        return generateSourceCodeSyntax(eTypeCodeSyntax);
    }
    
    /**
     * Genera y devuelve una Linea de Código fuente del Tipo de Sintaxis solicitada para la representación del <code>Componente</code>.
     * @param strEnumTypeCodeSyntax Nombre de la Enumeración.
     * @return Linea de Código Fuente.
     */
    public CodeContextLine generateSingleSourceCodeSyntax(String strEnumTypeCodeSyntax){
        EnumTypeCodeSyntax eTypeCodeSyntax = EnumTypeCodeSyntax.valueOf(strEnumTypeCodeSyntax);
        return generateSingleSourceCodeSyntax(eTypeCodeSyntax);
    }    
    
    /**
     * Genera y devuelve una colección de Código fuente del Tipo de Sintaxis solicitada para la representación del <code>Componente</code>.
     * @param eTypeCodeSyntax Tipo de Sintaxis del Código Fuente que se generará.
     * @return Colección de Lineas de Código Fuente.
     */
    public abstract ArrayList<CodeContextLine> generateSourceCodeSyntax(EnumTypeCodeSyntax eTypeCodeSyntax);
    
    /**
     * Genera y devuelve una Linea de Código fuente del Tipo de Sintaxis solicitada para la representación del <code>Componente</code>.
     * @param eTypeCodeSyntax Tipo de Sintaxis del Código Fuente que se generará.
     * @return Linea de Código Fuente.
     */
    public abstract CodeContextLine generateSingleSourceCodeSyntax(EnumTypeCodeSyntax eTypeCodeSyntax);
    
    /**
     * Devuelve el Código Fuente de la Sentencia de Importación del Control ó Contenedor
     * representado por el <code>Componente</code>.
     * @return Linea de Código Fuente Encapsulado.
     */
    protected CodeContextLine generateSourceCodeSyntaxImport(){
        try{            
            String strImport = "import " + objClassSwing.getCanonicalName() + ";";
            CodeContextLine objSourceLineCode = new CodeContextLine(strImport);
            return objSourceLineCode;            
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }       
    
    /**
     * Devuelve el Código Fuente de la Sentencia de Definición del Control ó Contenedor
     * representado por el <code>Componente</code>.
     * @param canonicalDefinition Determina el Tipo de Definición Simple o Canonica la
     * cual determina la Ruta parcial o Total del ClassPath del Control ó Contenedor.
     * @return Linea de Código Fuente Encapsulado.
     */
    protected CodeContextLine generateSourceCodeSyntaxDefinition(boolean canonicalDefinition){
        try{            
            String strDefinition = "private " + 
                ((canonicalDefinition) ? objClassSwing.getCanonicalName() : objClassSwing.getSimpleName()) + " " + getName() + ";";
            CodeContextLine objSourceLineCode = new CodeContextLine(strDefinition);                    
            return objSourceLineCode;            
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    /**
     * Devuelve el Código Fuente de la Sentencia de Importación del Scroll que 
     * Soportará el Contenedor representado por el <code>Componente</code>.
     * @return Linea de Código Fuente Encapsulado.
     */
    protected CodeContextLine generateSourceCodeSyntaxImportAsociateModel(){
        try{            
            String strImport = "import javax.swing.JScrollPane;";
            CodeContextLine objSourceLineCode = new CodeContextLine(strImport);
            return objSourceLineCode;            
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    /**
     * Devuelve el Código Fuente de la Sentencia de Inicialización del Control ó Contenedor
     * representado por el <code>Componente</code>.
     * @param canonicalDefinition Determina el Tipo de Definición Simple o Canonica la
     * cual determina la Ruta parcial o Total del ClassPath del Control ó Contenedor.
     * @return Linea de Código Fuente Encapsulado.
     */
    protected CodeContextLine generateSourceCodeSyntaxInitialization(boolean canonicalDefinition){
        try{            
            String strInitialization = getName() + " = new " + 
                ((canonicalDefinition) ? objClassSwing.getCanonicalName() : objClassSwing.getSimpleName()) + "();";
            CodeContextLine objSourceLineCode = new CodeContextLine(strInitialization);                    
            return objSourceLineCode;            
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    /**
     * Devuelve el Código Fuente de la Sentencia de Definición del Control Scroll
     * que soportará el Control Contenedor de la Colección de Objetos
     * representado por el <code>Componente</code>.
     * @param canonicalDefinition Determina el Tipo de Definición Simple o Canonica la
     * cual determina la Ruta parcial o Total del ClassPath del Control ó Contenedor.
     * @return Linea de Código Fuente Encapsulado.
     */
    public CodeContextLine generateSourceCodeSyntaxDefinitionAsociateScroll(boolean canonicalDefinition){
        try{            
            String strDefinition = "private " + 
                ((canonicalDefinition) ? "javax.swing.JScrollPane " : "JScroll ") + "objScrollPane" + getName() + ";";
            CodeContextLine objSourceLineCode = new CodeContextLine(strDefinition);                    
            return objSourceLineCode;            
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    /**
     * Devuelve el Código Fuente de la Sentencia de Inicialización del Control Scroll
     * que soportará el Control Contenedor de la Colección de Objetos
     * representado por el <code>Componente</code>.
     * @param canonicalDefinition Determina el Tipo de Definición Simple o Canonica la
     * cual determina la Ruta parcial o Total del ClassPath del Control ó Contenedor.
     * @return Linea de Código Fuente Encapsulado.
     */
    public CodeContextLine generateSourceCodeSyntaxInitializationAsociateScroll(boolean canonicalDefinition){
        try{            
            String strInitialization = "objScrollPane" + getName() + " = new " + 
                ((canonicalDefinition) ? "javax.swing.JScrollPane " : "JScroll ") + "(" + getName() + ");";
            CodeContextLine objSourceLineCode = new CodeContextLine(strInitialization);                    
            return objSourceLineCode;            
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }
    
    /**
     * Devuelve el Código Fuente de la Colección de Propiedades Aplicadas a la 
     * Representación soportada por el <code>Componente</code>.
     * @param canonicalDefinition 
     * @return Colección de Propiedades Aplicadas a la 
     * Representación soportada por el <code>Componente</code>.
     */
    public ArrayList<CodeContextLine> generateSourceCodeSyntaxCollectionProperties(boolean canonicalDefinition){
        try{            
            ArrayList<CodeContextLine> objSourceCode = new ArrayList<CodeContextLine>();
            for(Propiedad objPropiedad : objPropiedadesDisponibles){
                if(!UtilCodeContext.isIgnoreProperties(objPropiedad)){
                    objSourceCode.add(generateSourceCodeSyntaxProperties(objPropiedad, canonicalDefinition));
                }
            }            
            return objSourceCode;            
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }    
    
    /**
     * Devuelve el Código Fuente de la Sentencia de Definición de la Propiedad aplicada
     * al Control representado por el <code>Componente</code>.
     * @param objPropiedad Propiedad que genera la Sentencia de Definición.
     * @param canonicalDefinition 
     * @return Linea de Código Fuente Encapsulado.
     */
    protected CodeContextLine generateSourceCodeSyntaxProperties(Propiedad objPropiedad, boolean canonicalDefinition){
        try{            
            String strProperties = prepararPropiedadSet(objPropiedad);            
            strProperties = (strProperties.isEmpty() || strProperties.equals("\"\"")) ? "" : getName() + "." + objPropiedad.getSet() + "(" + strProperties + ");";
            CodeContextLine objSourceLineCode = new CodeContextLine(strProperties);                                
            return objSourceLineCode;            
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }     
    
    private String prepararPropiedadSet(Propiedad objPropiedad){
        String value = "";        
        for(ParametroPropiedad objParametro : objPropiedad.getObjParametrosSet()){
            value += prepararParametroPropiedad(objPropiedad, objParametro) + " ,";            
        }
        return value.isEmpty() ? value : value.substring(0, value.length() - 2);
    }
    
     private String prepararParametroPropiedad(Propiedad objPropiedad, ParametroPropiedad objParametro){
        String value;        
        if(objParametro.isPrimitive()){
            value = prepararParametroPrimitivo(objPropiedad, objParametro);
        }
        else{//Es un Objeto
            value = prepararParametroObjeto(objPropiedad, objParametro);
        }        
        return value;
    }
     
    /**
     *
     * @param objPropiedad
     */
    public static void configurarPropiedad(Propiedad objPropiedad){
        try{            
            if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_TEXT)){
                
            }
            else if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_TOOLTIPS)){
                
            }            
            else if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_ENABLED)){
                
            }
            else if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_OPAQUE)){
                
            }
            else if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_EDITABLE)){
                
            }
            else if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_SELECTED)){
                
            }
            else if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_FOREGROUND)){
                
            }
            else if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_BACKGROUND)){
                
            }
            else if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_ICON)){
                
            }            
        }catch(java.lang.NullPointerException ex){
            UtilRender.printlnConsole(ex.getMessage(), UtilRender.ACTION_ERROR, true);
        }       
    } 
     
    private String prepararParametroPrimitivo(Propiedad objPropiedad, ParametroPropiedad objParametro){
        String value = "";        
        if(objParametro.isPrimitive()){
            if(!objParametro.getStrValue().isEmpty()){
                value += objParametro.getStrValue();
            }
            else if(!objParametro.getStrValueDefault().isEmpty()){
                value += objParametro.getStrValueDefault();
            }
            else{
                if(objParametro.getStrClassPath().equals("boolean")){
                    value += "false";
                }
                else if(objParametro.getStrClassPath().equals("byte")){
                    value += "0";
                }
                else if(objParametro.getStrClassPath().equals("int")){
                    value += "0";
                }
                else if(objParametro.getStrClassPath().equals("long")){
                    value += "0";
                }        
                else if(objParametro.getStrClassPath().equals("float")){
                    value += "0";
                }
                else if(objParametro.getStrClassPath().equals("double")){
                    value += "0";
                }
                else if(objParametro.getStrClassPath().equals("char")){
                    value += "'0'";
                }
            }
        }        
        return value;
    } 
    
    private String prepararParametroObjeto(Propiedad objPropiedad, ParametroPropiedad objParametro){
        String value = "";          
        if(!objParametro.isPrimitive()){
            if(objParametro.getStrValue() != null){
                if(objParametro.getStrClassPath().equals(String.class.getCanonicalName())){                                    
                    if(objPropiedad.getName().equals(Propiedad.NAME_PROPERTIES_ICON)){                        
                        value = objParametro.getStrValue();                        
                        if(!value.isEmpty()){
                            File objFile = new File(value);
                            if(Utileria.getExecuteMode() == Utileria.SourceCodeMode &&
                                    objPropiedad.isSwapKey(Propiedad.NAME_PROPERTIES_ICON) && 
                                    isSwapKey("package")){
                               String strPackage = String.valueOf(getObjSwapValues().get("package"));
                               value = "new javax.swing.ImageIcon(getClass().getResource(\"/" + getStrPaqueteToFile(strPackage) + "/" + objFile.getName() + "\"))"; 
                            }
                            else{                                
                                String strPath = objFile.toURI().getRawPath();
                                value = "new javax.swing.ImageIcon(\"" + strPath + "\")";                            
                            }
                        }
                    }
                    else{
                        value = prepararParametroObjetoString(objPropiedad, objParametro);
                    }
                }                        
                else if(objParametro.getStrClassPath().equals(Color.class.getCanonicalName())){
                    value = prepararParametroObjetoColor(objPropiedad, objParametro);
                }
            }
        }        
        return value;
    } 
    
    private static String prepararParametroObjetoString(Propiedad objPropiedad, ParametroPropiedad objParametro){
        String value;        
        if(!objParametro.getStrValue().isEmpty()){
            value = "\"" + objParametro.getStrValue() + "\"";
        }
        else if(!objParametro.getStrValueDefault().isEmpty()){
            value = "\"" + objParametro.getStrValueDefault() + "\"";
        }
        else{
            value = "\"\"";
        }
        return value;
    }
    
    private static String prepararParametroObjetoColor(Propiedad objPropiedad, ParametroPropiedad objParametro){
        String value;
        if(!objParametro.getStrValue().isEmpty()){
            value = "new java.awt.Color(" + objParametro.getStrValue() + ")";
        }
        else if(!objParametro.getStrValueDefault().isEmpty()){
            value = "new java.awt.Color(" + objParametro.getStrValueDefault() + ")";
        }
        else{
            value = "new java.awt.Color(Color.BLACK)";
        }
        return value;
    }
    
    /**
     * Devuelve el Código Fuente de la Sentencia de Definición de las Reglas de ubicación
     * que se aplicarán al Control representado por el <code>Componente</code>.
     * @param objGridBagConstraints Objeto que contiene las reglas de ubicación en la interfaz gráfica.
     * @param canonicalDefinition 
     * @return Linea de Código Fuente Encapsulado.
     */
    public CodeContextLine generateSourceCodeSyntaxGridBagConstraints(GridBagConstraints objGridBagConstraints, boolean canonicalDefinition) {
        String strComponente;
        if(this.isComponentCollection()){
            strComponente = Utileria.leerRecursoTexto("Utileria.coleccion.contenedor.alias") + getName();
        }
        else if(this instanceof ComponenteDistribuidorIntegrador || 
                this instanceof ComponenteDistribuidorGeneradorClaseCompleja){
            strComponente = "obj" + getName();
        }
        else{
            strComponente = getName();
        }
        String strGridBagConstraints =  "addToLayout(" + strComponente + ", " + objGridBagConstraints.gridx + ", " +
                objGridBagConstraints.gridy + ", " + objGridBagConstraints.gridwidth + ", " +
                objGridBagConstraints.gridheight + ", " + objGridBagConstraints.weightx + ", " +
                objGridBagConstraints.weighty + ", " + objGridBagConstraints.anchor + ", " + 
                objGridBagConstraints.fill + ", " + objGridBagConstraints.insets.top + ", " +
                objGridBagConstraints.insets.left + ", " + objGridBagConstraints.insets.bottom + ", " +
                objGridBagConstraints.insets.right + ", " + objGridBagConstraints.ipadx + ", " +
                objGridBagConstraints.ipady + ");";
        CodeContextLine objSourceLineCode = new CodeContextLine(strGridBagConstraints);
        return objSourceLineCode;            
    }    
    
    /**
     *
     * @param canonicalDefinition
     * @return
     */
    public ArrayList<CodeContextLine> generateSourceCodeSyntaxCollectionEvents(boolean canonicalDefinition){
        try{            
            ArrayList<CodeContextLine> objSourceCode = new ArrayList<CodeContextLine>();
            for(Oyente<Componente> objOyente : objOyentes){
                for(EventoOyente objEvento : objOyente.getObjEventos()){
                    if(objEvento.isIncluido()){
                        objSourceCode.add(generateSourceCodeSyntaxEvent(objEvento, canonicalDefinition));
                    }
                }
            }            
            return objSourceCode;            
        }catch(java.lang.Exception ex){
            Logger.getLogger(Componente.class.getName()).log(Level.SEVERE, null, ex);
        }
        return null;
    }        
    
    /**
     *
     * @param objEvento
     * @param canonicalDefinition
     * @return
     */
    public CodeContextLine generateSourceCodeSyntaxEvent(EventoOyente objEvento, boolean canonicalDefinition){
        Oyente objOyente = objEvento.getObjOyente();
        CodeContextLine objSourceLineCode = new CodeContextLine();        
        objSourceLineCode.addElement("name", getName());
        objSourceLineCode.addElement("interface", objOyente.getStrInterfaz());
        objSourceLineCode.addElement("package", objOyente.getStrPaquete());
        
        String strEvento = objEvento.getStrNombre();
        strEvento = Character.toUpperCase(strEvento.charAt(0)) + strEvento.substring(1);
        objSourceLineCode.addElement("method", strEvento);
        objSourceLineCode.addElement("event", objEvento.getStrNombre());
        objSourceLineCode.addElement("action", objOyente.getStrAccion());
        objSourceLineCode.addElement("evt", objOyente.getStrVar());        
        return objSourceLineCode;
    }
    
    /**
     *
     * @param canonicalDefinition
     * @return
     */
    public CodeContextLine generateSourceCodeSyntaxFunctionGetSet(boolean canonicalDefinition){        
        CodeContextLine objSourceLineCode = new CodeContextLine();        
        objSourceLineCode.addElement("name", getName());        
        if(objClassSwing != null){
            String strSimpleName = objClassSwing.getSimpleName();
            String strCanonicalName = objClassSwing.getCanonicalName();
            objSourceLineCode.addElement("classpath", (canonicalDefinition) ? strCanonicalName : strSimpleName);
        }
        else{
            objSourceLineCode.addElement("classpath", strClassPath);
        }
        return objSourceLineCode;
    }
    
    /**
     *
     * @param strEvento
     * @param canonicalDefinition
     * @return
     */
    public CodeContextLine generateSourceCodeSyntaxEvent(String strEvento, boolean canonicalDefinition){
        EventoOyente objEventoOyente = GeneradorComponentes.findEventoOyente(strEvento);
        return generateSourceCodeSyntaxEvent(objEventoOyente, canonicalDefinition);
    }
    
    /**
     *
     * @return
     */
    public CodeContextLine getSourceCodeSyntaxEvent(){
        return null;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj instanceof Componente){
            Componente objComponente = (Componente) obj;
            return this.getName().equals(objComponente.getName());
        }
        return super.equals(obj);
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 17 * hash + (this.dni != null ? this.dni.hashCode() : 0);
        return hash;
    }
    
    /**
     *
     * @param strAlias
     * @return
     */
    public Propiedad findPropiedadForAlias(String strAlias){
        try{
            for(Propiedad objPropiedad : this.getObjPropiedadesDisponibles()){
                if(strAlias.equals(objPropiedad.getAlias())){
                    return objPropiedad;
                }
            }
        }catch(java.lang.NullPointerException ex){            
            UtilRender.printlnConsole("Nulo", ex.getMessage(), UtilRender.ACTION_ERROR);
        }
        return null;
    }
    
    /**
     * Devuelve el Paquete Asignado al <code>Componente</code> en Formato Archivo.
     * @param strFilePaquete Definición del paquete.
     * @return Paquete Asignado al <code>ComponenteDistribuidor</code> en Formato Archivo.
     */
    public String getStrPaqueteToFile(String strFilePaquete) {        
        char c = Utileria.separador.charAt(0);
        strFilePaquete = strFilePaquete.replace('.', c);
        return strFilePaquete;
    }    
}
